package cn.tedu.project.oa.dingding;


import cn.tedu.project.oa.attendanceRule.pojo.entity.WorkingShift;
import cn.tedu.project.oa.management.pojo.dto.DingDingManagementAddParam;
import cn.tedu.project.oa.management.pojo.dto.DingDingMemberUpdateParam;
import cn.tedu.project.oa.management.pojo.dto.MemberUpdateParam;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.*;
import com.dingtalk.api.response.*;
import com.taobao.api.ApiException;
import com.taobao.api.internal.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

@Service
@Slf4j
public class DingDingService {
    public static final String access_token = getAccessToken();
    /**
     * 通过调用接口获取access_token
     * dingtalk
     * @return
     * String
     * 2021-1-20
     */
    private static String getAccessToken() {
        DingTalkClient client = new DefaultDingTalkClient(DingDingConstant.GET_TOKEN_URL);
        OapiGettokenRequest request = new OapiGettokenRequest();
        request.setAppkey(DingDingConstant.APP_KEY);
        request.setAppsecret(DingDingConstant.APP_SECRET);
        request.setHttpMethod("GET");
        OapiGettokenResponse response = null;
        try {
            response = client.execute(request);
        } catch (ApiException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return response.getAccessToken();
    }

    //更新参与考勤人员
    public static Boolean updateMember(DingDingMemberUpdateParam memberUpdateParam) throws ApiException {
        DingTalkClient client = new DefaultDingTalkClient(DingDingConstant.UPDATE_MEMBER_URL);
        OapiAttendanceGroupMemberUpdateRequest req = new OapiAttendanceGroupMemberUpdateRequest();
        req.setOpUserId("user123");
        req.setGroupId(memberUpdateParam.getId());
        req.setScheduleFlag(0L);
        OapiAttendanceGroupMemberUpdateRequest.TopGroupMemberUpdateParam updateParam = new OapiAttendanceGroupMemberUpdateRequest.TopGroupMemberUpdateParam();
        updateParam.setAddUsers(memberUpdateParam.getAddUserList());
        updateParam.setRemoveUsers(memberUpdateParam.getRemoveUserList());
        req.setUpdateParam(updateParam);
        OapiAttendanceGroupMemberUpdateResponse rsp = client.execute(req, access_token);
        System.out.println(rsp.getBody());
        return rsp.getSuccess();
    }

    //删除考勤管理组
    public static void deleteManagementById(Long id) throws ApiException {
        String GroupKey = idToKey(id);
        DingTalkClient client = new DefaultDingTalkClient(DingDingConstant.DELETE_MANAGEMENT_URL);
        OapiAttendanceGroupDeleteRequest req = new OapiAttendanceGroupDeleteRequest();
        req.setOpUserid(DingDingConstant.ADMIN_ID);
        req.setGroupKey(GroupKey);
        OapiAttendanceGroupDeleteResponse rsp = client.execute(req, access_token);
        System.out.println(rsp.getBody());
    }
    public static String idToKey(Long id) throws ApiException {
        DingTalkClient client = new DefaultDingTalkClient(DingDingConstant.ID_TO_KEY_URL);
        OapiAttendanceGroupsIdtokeyRequest req = new OapiAttendanceGroupsIdtokeyRequest();
        req.setOpUserId(DingDingConstant.ADMIN_ID);
        req.setGroupId(id);
        OapiAttendanceGroupsIdtokeyResponse rsp = client.execute(req, access_token);
        System.out.println(rsp.getBody());
        return rsp.getResult();
    }

    //新建考勤管理组
    public static Long addManagement(DingDingManagementAddParam managementAddParam) throws ApiException {
        // 创建钉钉客户端实例，指定请求的API URL
        DingTalkClient client = new DefaultDingTalkClient(DingDingConstant.ADD_MANAGEMENT_URL);
        // 创建一个添加考勤组的请求实例
        OapiAttendanceGroupAddRequest req = new OapiAttendanceGroupAddRequest();
        // 设置执行操作的用户ID（通常是操作员ID）
        req.setOpUserId(DingDingConstant.ADMIN_ID);
        // 创建一个TopGroupVo对象来保存考勤组的相关信息
        OapiAttendanceGroupAddRequest.TopGroupVo topGroupVo = new OapiAttendanceGroupAddRequest.TopGroupVo();
        // 设置考勤组所有者
        topGroupVo.setOwner("user1");
        // 允许员工选择班级
        topGroupVo.setEnableEmpSelectClass(true);
        // 设置企业的corpId
        topGroupVo.setCorpId(DingDingConstant.CORP_ID);
        // 设置是否跳过节假日
        topGroupVo.setSkipHolidays(true);
        // 设置特殊日期，如加班和休息日
        topGroupVo.setSpecialDays("{\"onDuty\":{1400000:123,1400001:123},\"offDuty\":[1400000,1400001]}");
        // 启用外部摄像头打卡
        topGroupVo.setEnableOutsideCameraCheck(managementAddParam.getEnableOutsideCameraCheck());

        // 初始化位置列表
        List<OapiAttendanceGroupAddRequest.TopPositionVo> positionVos = new ArrayList<OapiAttendanceGroupAddRequest.TopPositionVo>();
        // 创建一个位置信息对象
        OapiAttendanceGroupAddRequest.TopPositionVo topPositionVo = new OapiAttendanceGroupAddRequest.TopPositionVo();
        // 添加位置信息到列表
        positionVos.add(topPositionVo);
        // 设置地址信息
        topPositionVo.setAddress(managementAddParam.getAddress());
        // 设置企业corpId（与上面一致）
        topPositionVo.setCorpId(DingDingConstant.CORP_ID);
        // 设置纬度坐标
        topPositionVo.setLatitude(managementAddParam.getLatitude().toString());
        // 设置精度（0代表精确到点）
        topPositionVo.setAccuracy("0");
        // 设置标题或地点名称
        topPositionVo.setTitle(managementAddParam.getTitle());
        // 设置经度坐标
        topPositionVo.setLongitude(managementAddParam.getLongitude().toString());
        topGroupVo.setPositions(positionVos);

        // 设置是否修改成员
        topGroupVo.setModifyMember(true);
        // 设置考勤类型
        topGroupVo.setType("FIXED");
        // 启用人脸识别打卡
        topGroupVo.setEnableFaceCheck(managementAddParam.getEnableFaceCheck());
        // 检查健康码
        topGroupVo.setCheckNeedHealthyCode(false);
        // 启用摄像头打卡
        topGroupVo.setEnableCameraCheck(managementAddParam.getEnableFaceCheck());

        // 初始化班次列表
        List<OapiAttendanceGroupAddRequest.TopShiftVo> topShiftVos = new ArrayList<OapiAttendanceGroupAddRequest.TopShiftVo>();
        // 创建一个班次信息对象
        OapiAttendanceGroupAddRequest.TopShiftVo topShiftVo = new OapiAttendanceGroupAddRequest.TopShiftVo();
        // 添加班次信息到列表
        topShiftVos.add(topShiftVo);
        // 设置班次ID
        topShiftVo.setId(managementAddParam.getWorkingShiftId());
        // 设置考勤组中的班次列表
        topGroupVo.setShiftVoList(topShiftVos);
        // 启用外部打卡
        topGroupVo.setEnableOutsideCheck(managementAddParam.getEnableOutsideCheck());

        // 初始化成员列表
        List<OapiAttendanceGroupAddRequest.TopMemberVo> memberVos = new ArrayList<OapiAttendanceGroupAddRequest.TopMemberVo>();
        // 创建一个成员信息对象
        OapiAttendanceGroupAddRequest.TopMemberVo topMemberVo = new OapiAttendanceGroupAddRequest.TopMemberVo();
        for (String userId : managementAddParam.getUserList()){
            // 添加成员信息到列表
            memberVos.add(topMemberVo);
            // 设置成员的角色
            topMemberVo.setRole("Attendance");
            // 设置企业corpId（与上面一致）
            topMemberVo.setCorpId(DingDingConstant.CORP_ID);
            // 设置成员类型
            topMemberVo.setType("StaffMember");
            // 设置用户ID
            topMemberVo.setUserId(userId);
        }

        // 设置考勤组中的成员列表
        topGroupVo.setMembers(memberVos);
        // 设置考勤组名称
        topGroupVo.setName(managementAddParam.getName());
        // 设置是否启用第二天考勤
        topGroupVo.setEnableNextDay(false);
        // 设置管理员列表
        topGroupVo.setManagerList(Collections.singletonList(DingDingConstant.ADMIN_ID));
        // 设置默认班级ID
        for (Long id : managementAddParam.getWorkingClassList()){
            if (id != 0){
                managementAddParam.setWorkingShiftId(id);
            }
        }
        topGroupVo.setDefaultClassId(managementAddParam.getWorkingShiftId());
        topGroupVo.setWorkdayClassList(managementAddParam.getWorkingClassList());
        // 设置偏移量
        topGroupVo.setOffset(500L);

        // 创建权限管理信息对象
        OapiAttendanceGroupAddRequest.TopGroupManageRolePermissionVo groupManageRolePermissionVo = new OapiAttendanceGroupAddRequest.TopGroupManageRolePermissionVo();
        // 设置排班权限
        groupManageRolePermissionVo.setSchedule("w");
        // 设置组成员管理权限
        groupManageRolePermissionVo.setGroupMember("w");
        // 设置组类型查看权限
        groupManageRolePermissionVo.setGroupType("r");
        // 设置打卡时间设置权限
        groupManageRolePermissionVo.setCheckTime("w");
        // 设置打卡位置类型查看权限
        groupManageRolePermissionVo.setCheckPositionType("r");
        // 设置加班规则查看权限
        groupManageRolePermissionVo.setOverTimeRule("r");
        // 设置摄像头打卡设置权限
        groupManageRolePermissionVo.setCameraCheck("w");
        // 设置外部打卡设置权限
        groupManageRolePermissionVo.setOutSideCheck("w");
        // 设置考勤组中的权限管理信息
        topGroupVo.setResourcePermissionMap(groupManageRolePermissionVo);

        // 初始化Wi-Fi列表
        List<OapiAttendanceGroupAddRequest.TopWifiVo> topWifiVos = new ArrayList<OapiAttendanceGroupAddRequest.TopWifiVo>();
        // 创建一个Wi-Fi信息对象
        OapiAttendanceGroupAddRequest.TopWifiVo topWifiVo = new OapiAttendanceGroupAddRequest.TopWifiVo();
        // 添加Wi-Fi信息到列表
        topWifiVos.add(topWifiVo);
        // 设置MAC地址
        topWifiVo.setMacAddr(managementAddParam.getMacAddr());
        // 设置SSID
        topWifiVo.setSsid(managementAddParam.getSsid());
        // 设置企业corpId（与上面一致）
        topWifiVo.setCorpId(DingDingConstant.CORP_ID);
        // 设置考勤组中的Wi-Fi列表
        topGroupVo.setWifis(topWifiVos);
        // 设置是否禁用无排班时的打卡
        topGroupVo.setDisableCheckWithoutSchedule(false);
        // 设置自由打卡开始分钟数
        topGroupVo.setFreecheckDayStartMinOffset(240L);
        // 设置是否禁用休息时的打卡
        topGroupVo.setDisableCheckWhenRest(managementAddParam.getDisableCheckWhenRest());
        // 设置请求体中的考勤组信息
        req.setTopGroup(topGroupVo);
        // 执行请求，并获取响应结果
        OapiAttendanceGroupAddResponse rsp = client.execute(req, access_token);
        // 输出响应结果
        System.out.println(rsp.getBody());
        return rsp.getResult().getId();
    }


    //删除班次
    public static void deleteShiftById(Long id) throws ApiException {
        //
        DingTalkClient client = new DefaultDingTalkClient(DingDingConstant.DELETE_SHIFT_URL);
        OapiAttendanceShiftDeleteRequest req = new OapiAttendanceShiftDeleteRequest();
        req.setOpUserId("user456");
        req.setShiftId(id);
        OapiAttendanceShiftDeleteResponse rsp = client.execute(req, access_token);
        System.out.println(rsp.getBody());
    }


    //新建班次
    public static Long addShift(WorkingShift workingShift) throws ApiException {
        log.debug("新建班次参数："+workingShift);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String checkInTime;
        String checkOutTime;
        checkInTime = simpleDateFormat.format(workingShift.getCheckInTime());
        checkOutTime = simpleDateFormat.format(workingShift.getCheckOutTime());

        DingTalkClient client = new DefaultDingTalkClient(DingDingConstant.ADD_SHIFT_URL);
        OapiAttendanceShiftAddRequest request = new OapiAttendanceShiftAddRequest();
        OapiAttendanceShiftAddRequest.TopAtClassVo topAtClassVo = new OapiAttendanceShiftAddRequest.TopAtClassVo();
        topAtClassVo.setOwner(workingShift.getUsername());
        topAtClassVo.setClassGroupName("测试班次组");
        topAtClassVo.setCorpId(DingDingConstant.CORP_ID);
        topAtClassVo.setName(workingShift.getName());
        List<OapiAttendanceShiftAddRequest.TopAtSectionVo> sectionVos = new ArrayList<>();
        OapiAttendanceShiftAddRequest.TopAtSectionVo sectionVo = new OapiAttendanceShiftAddRequest.TopAtSectionVo();
        List<OapiAttendanceShiftAddRequest.TopAtTimeVo> timeVos = new ArrayList<>();

        //设置上班打卡
        OapiAttendanceShiftAddRequest.TopAtTimeVo timeVo = new OapiAttendanceShiftAddRequest.TopAtTimeVo();
        timeVo.setAcross(0L);
        timeVo.setBeginMin(workingShift.getCheckInBeginMin());
        timeVo.setCheckTime(StringUtils.parseDateTime(checkInTime));
        timeVo.setCheckType("OnDuty");
        timeVo.setEndMin(workingShift.getCheckInEndMin());
        timeVo.setFreeCheck(false);

        //设置下班打卡
        OapiAttendanceShiftAddRequest.TopAtTimeVo timeVo1 = new OapiAttendanceShiftAddRequest.TopAtTimeVo();
        timeVo1.setAcross(0L);
        timeVo1.setEndMin(workingShift.getCheckOutBeginMin());
        timeVo1.setCheckTime(StringUtils.parseDateTime(checkOutTime));
        timeVo1.setCheckType("OffDuty");
        timeVo1.setEndMin(workingShift.getCheckOutEndMin());
        timeVo1.setFreeCheck(false);

        timeVos.add(timeVo);
        timeVos.add(timeVo1);
        sectionVo.setTimes(timeVos);
        sectionVos.add(sectionVo);
        topAtClassVo.setSections(sectionVos);
        OapiAttendanceShiftAddRequest.TopAtClassSettingVo settingVo = new OapiAttendanceShiftAddRequest.TopAtClassSettingVo();
        topAtClassVo.setSetting(settingVo);

        //设置休息时间
        if (workingShift.getRestStartTime() != null && workingShift.getRestEndTime() != null){
            //设置休息开始时间
            OapiAttendanceShiftAddRequest.TopAtTimeVo restBeginTime = new OapiAttendanceShiftAddRequest.TopAtTimeVo();
            settingVo.setRestBeginTime(restBeginTime);
            restBeginTime.setFreeCheck(false);
            restBeginTime.setAcross(1L);
            restBeginTime.setCheckType("OnDuty");
            restBeginTime.setFreeCheck(false);
            restBeginTime.setCheckTime(StringUtils.parseDateTime(
                    simpleDateFormat.format(workingShift.getRestStartTime())
            ));
            //设置休息结束时间
            OapiAttendanceShiftAddRequest.TopAtTimeVo restEndTime = new OapiAttendanceShiftAddRequest.TopAtTimeVo();
            settingVo.setRestEndTime(restEndTime);
            restEndTime.setAcross(1L);
            restEndTime.setCheckType("OffDuty");
            restEndTime.setFreeCheck(false);
            restEndTime.setCheckTime(StringUtils.parseDateTime(
                    simpleDateFormat.format(workingShift.getRestEndTime())
            ));
        }

        settingVo.setCorpId(DingDingConstant.CORP_ID);
        settingVo.setIsDeleted("N");
        settingVo.setAbsenteeismLateMinutes(workingShift.getLateAbsences());
        settingVo.setIsFlexible(false);
        settingVo.setSeriousLateMinutes(workingShift.getSeriouslyLate());
        request.setOpUserId("user456");
        request.setShift(topAtClassVo);

        //向钉钉发送新建班次请求
        OapiAttendanceShiftAddResponse response = client.execute(request, getAccessToken());
        Long id = response.getResult().getId();
        log.debug(response.getBody());
        return id;
    }


    //获取钉钉用户信息
    public OapiV2UserGetResponse getUser(String userId){
        OapiV2UserGetResponse rsp = null;
        try {
            DingTalkClient client =
                    new DefaultDingTalkClient(DingDingConstant.GET_USER_URL);
            OapiV2UserGetRequest req = new OapiV2UserGetRequest();
            req.setUserid(userId);
            req.setLanguage("zh_CN");
            rsp = client.execute(req, access_token);
//            log.debug(access_token);
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return rsp;
    }

    //根据手机号查询用户Id
    public static String getUserIdByMobile(String mobile) throws ApiException {
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/getbymobile");
        OapiV2UserGetbymobileRequest req = new OapiV2UserGetbymobileRequest();
        req.setMobile(mobile);
        OapiV2UserGetbymobileResponse rsp = client.execute(req, access_token);
        System.out.println(rsp.getBody());
        if (rsp.getResult() != null) {
            return rsp.getResult().getUserid();
        }
        return null;
    }
}
